package com.wjc.httpserver;

import info.qingshui.browser.hk.setting.Setting;

import java.io.IOException;

import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import android.content.Context;
import android.util.Log;
import socks.Socks5Proxy;
import socks.UserPasswordAuthentication;

public class HttpServer {
	private static final String TAG = "HttpServer";
	/**
	 * 本地监听的ServerSocket
	 * */
	private ServerSocket localListenSocket;
	
	private Context context;
	
	public static ConcurrentHashMap<String, ConnectionDisposeThread> requestPool = new ConcurrentHashMap<String, ConnectionDisposeThread> ();
	/**
	 * 当前服务的端口
	 * */
	/**
	 * 默认服务端口
	 * */
	// 配置信息

	private static final int localPort = 18080;


	private ListenThread listenThread;

	/**
	 * 本类对象
	 * */
	private static HttpServer localServer;
	/**
	 * 状态
	 * */
	private int state;
	public static final int RUN = 0x1;
	public static final int STOP = 0x2;
	public static final int ERROR = 0x3;
	
	
	/**
	 * 代理配置
	 * */
	//private Socks5Proxy proxySet;
	
	


	// private static ConnectionDisposeThread thread;
	/**
	 * 内部类区域
	 * */
	/**
	 * 处理线程
	 * */
	class ConnectionDisposeThread extends Thread {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private Socket client;
		private String key;//标识该线程的唯一ID
		private long sleepTime = 0;
		
		private Context context;

		public ConnectionDisposeThread(Context context, Socket client, String key, long sleepTime) {
			this.context = context;
			this.client = client;
			this.key = key;
			this.sleepTime = sleepTime;

		}

		public void run() {
			this.setName("RequestThread");
			try {
				new Socket5Connection(context, client,   sleepTime).doDispose();
				
			} catch (Throwable e) {
				Log.e(HttpServer.class.getSimpleName(), "run", e);
				
			} finally {
				HttpServer.requestPool.remove( this.key);
			}

		}

	}

	/**
	 * 监听服务线程
	 * */
	class ListenThread extends Thread {
		private Context context;
		public ListenThread(Context context) {
			this.context = context;
		}

		@Override
		public void run() {
			this.setName("ListenThread");
			try {
				localListenSocket = new ServerSocket(localPort);
				Log.d(TAG, "http server" + localPort + "启动成功：" + localListenSocket);
				while (state == RUN) {
					// 控制语句添加
					Socket client = localListenSocket.accept();
					Log.d(TAG, "添加新连接");
					String key = "" + System.currentTimeMillis();
					long sleeptime = 0;
					if ( HttpServer.requestPool.size() > 50 ) {
						HttpServer.requestPool.clear();
					}
					if( HttpServer.requestPool.size() > 3 ) {
						//太多现成在走，需要推迟部分现成的运行
						sleeptime =  (HttpServer.requestPool.size() - 3) * 500;
						if( sleeptime > 4000) {
							sleeptime = 4000;
						}
					}
					ConnectionDisposeThread cdt = new ConnectionDisposeThread(this.context, client,key,sleeptime);
					cdt.start();
					HttpServer.requestPool.put(key, cdt);
				}
			} catch (Throwable e) {
				Log.e(HttpServer.class.getSimpleName(), "http server 启动失败", e);
			} finally {
				try {
					localListenSocket.close();
				} catch (IOException e) {
				
				}
			}

		}
	}

	public synchronized static HttpServer newInstance(Context context) {
		if (localServer == null) {
			localServer = new HttpServer(context);
		}
		return localServer;
	}

	private   HttpServer( Context context) {
		this.context = context;
	}

	/**
	 * 启动服务
	 * */
	public boolean start() {

		if (listenThread == null) {
			state = RUN;
			listenThread = new ListenThread( this.context );
			listenThread.start();

			return true;
		} else
			return false;
	}

	/**
	 * 停止服务
	 * */
	public boolean stop() {
		state = STOP;
		Socket5Connection.setState(STOP);
		if (listenThread == null || localListenSocket == null)
			return false;
		else {
			if (localListenSocket.isClosed()) {
				Log.d(TAG, "监听在停止前关闭");
			} else {
				Log.d(TAG, "正在关闭监听");
				try {
					if ( null != localListenSocket ) {
						localListenSocket.close();
					}
				} catch (IOException e) {
					Log.w(HttpServer.class.getSimpleName(), "HttpServer()", e);
				}
			}
			localServer = null;

			return true;
		}
	}

}
